Stuck in a pysftp Dilemma - Needing Help

by: GabrielTheodoulos, 8 years ago

Last edited: 8 years ago

What's Up Everyone, What's Going On??? (My Instructor's Favorite Greeting!)

I am taking an online class in Python, and my results are not the same as the results with the instructor.
He is teaching us about how to use the module pysftp, and while I have everything setup the way he does online, I am getting an error.

Here is my code (sans password ofc!)
<pre class='prettyprint lang-py'>
import pysftp as sftp


def push_file_to_server():
    s = sftp.Connection(host='138.68.31.129', username='root', password='**************)
    local_path = "testme.txt"
    remote_path = "/home/testme.txt"

    s.put(local_path, remote_path)
    s.close()

push_file_to_server()
</pre>

The results SHOULD be that I transfer file, 'testme.txt" to my remote server.
What II get instead is,

<pre class='prettyprint lang-py'>
E:Anaconda3python.exe E:/OneDrive/Python/GIT/DigitalCloud/pysftp_tutorial.py
E:Anaconda3libsite-packagespysftp__init__.py:61: UserWarning: Failed to load HostKeys from C:UsersJohnCalvin.sshknown_hosts.  You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
  warnings.warn(wmsg, UserWarning)
Traceback (most recent call last):
  File "E:/OneDrive/Python/GIT/DigitalCloud/pysftp_tutorial.py", line 12, in <module>
    push_file_to_server()
  File "E:/OneDrive/Python/GIT/DigitalCloud/pysftp_tutorial.py", line 5, in push_file_to_server
    s = sftp.Connection(host='138.68.31.129', username='root', password='*************
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "E:Anaconda3libsite-packagespysftp__init__.py", line 71, in get_hostkey
    raise SSHException("No hostkey for host %s found." % host)
paramiko.ssh_exception.SSHException: No hostkey for host 138.68.31.129 found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x000001E481390518>>
Traceback (most recent call last):
  File "E:Anaconda3libsite-packagespysftp__init__.py", line 1013, in __del__
    self.close()
  File "E:Anaconda3libsite-packagespysftp__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

Process finished with exit code 1
</pre>

Can anyone help?
Thanks!




You must be logged in to post. Please login or register an account.



Is this your very first time connecting to this server on said machine?

The very first time you connect to a remote server, you will save a host key on your machine. This is a way of verifying that the machine you think you are dealing with really is the machine you are dealing with in the future (protects against man in the middle attacks).

If you connect with something like putty, you will get a message that asks if you want to save the host key to your registry. I don't think I've ever attempted sftp without having first made a connection via putty or shell, so maybe that is why I have never seen this.

I am not sure how to save the host key initially with pysft, but you can disable it, it looks like, by adding cnopts.hostkeys = None in the parms.

I would personally suggest you go ahead and access the server with something like putty, since it looks like you are on windows, first, and save the host key. You should get a little popup the first time you connect to a server that asks if you want to save the host key. Hit yes there.


-Harrison 8 years ago

You must be logged in to post. Please login or register an account.


Yes!
You are correct.  I did access the server with PuTTY, and it did ask me to save the key.
But sadly, it still gives me the error.  :(

I recall you had us add modules via pip to our Python 3.  Could I have fouled up by adding them incorrectly?

-GabrielTheodoulos 8 years ago
Last edited 8 years ago

You must be logged in to post. Please login or register an account.


Possibly, or, for some other reason, the host key just isn't being saved.  Have you tried to just ignore it? You could also find the location of the hostkey that putty saved for you, and then do the cnopts.hostkeys.load(filename)

Haven't done it myself, but, before the connection, I am expecting that you'd do this like:

pysftp.cnopts.hostkeys.load(filename)

after the import, and before trying to connect, or

pysftp.cnopts.hostkeys = None

-Harrison 8 years ago

You must be logged in to post. Please login or register an account.


This is what I'm finding, and as a noobie, it's really frustrating me.
PuTTY  is saving the Host Key to the Registry [HKEY_CURRENT_USERSoftwareSimonTathamPuTTYSshHostKeys].

BUT, pysftp is looking for it in [C:UsersJohnCalvin.sshknown_hosts].

Any suggestions on how to resolve this?

I tried looking at PuTTY and see if I can change the location, but it's being obstinate.

Appreciating the help.



-GabrielTheodoulos 8 years ago

You must be logged in to post. Please login or register an account.


I'm having the same exact problem. Was wondering if you ever found a solution to this? ...tried the above suggestions to no success.

-vince184 8 years ago

You must be logged in to post. Please login or register an account.


No, I'm still waiting for a solution.  I've written to everyone from the authors of PuTTY to a dev who worked on the pysftp module.

From what I've boiled down, the problem lies in how PuTTY is storing the Host Keys.  Normally (from my understanding) host keys are stored in the location /users/{username}/.ssh/known_hosts/.  But with PuTTY being a Windows program, they are storing it in the Windows Registry [HKEY_CURRENT_USER/Software/SimonTatham/ PuTTY/SshHostKeys].  This is causing the module pysftp to not see the key, and thus hair-ball.

I tried looking into the Python module winreg, which should allow us to read the Windows Registry, but I have as yet resoled how to get winreg to pull the actual key.

My work around solution (which I HATE for security reasons) is to ignore the host key all-together.  This is how I wrote my program,


import pysftp as sftp

def push_file_to_server():
    cnopts = sftp.CnOpts()
    cnopts.hostkeys = None
    s = sftp.Connection(host='138.86.13.129', username='root', password='*********', cnopts=cnopts)
    local_path = "testme.txt"
    remote_path = "/home/testme.txt"

    s.put(local_path, remote_path)
    s.close()

push_file_to_server()


by adding cnopts, I am authorizing the program to ignore the host key and just continue.  This is BAD coding, as far as I'm concerned, b/c if we do this in real-life, we are opening ourselves to potential hacking.


-GabrielTheodoulos 8 years ago

You must be logged in to post. Please login or register an account.

no such thing as dilex or needx, do anyx nmw

-asdfzxh 7 years ago

You must be logged in to post. Please login or register an account.

I managed a work around for this on Ubuntu 16.  
I ran the sftp command from the command line using the identical parameters I was feeding to pysftp.  I am using a non standard port so it needed the -P switch    

sftp -P XXXX user_name@X.X.X.X  

This then created the key in .ssh/known_hosts and then pysftp worked as expected.
Note this is a different key to that produced by ssh

-jamesnt 6 years ago

You must be logged in to post. Please login or register an account.


Also ensure known_hosts has the correct permissions
chmod 644 ~/.ssh/known_hosts
chmod 700 ~/.ssh

-jamesnt 6 years ago

You must be logged in to post. Please login or register an account.